package com.example.mydemo.service.impl;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mydemo.entity.Clock;
import com.example.mydemo.entity.Employee;
import com.example.mydemo.entity.domain.EmployeeClockStatDTO;
import com.example.mydemo.mapper.ClockMapper;

import com.example.mydemo.mapper.DepMapper;
import com.example.mydemo.mapper.EmployeeMapper;
import com.example.mydemo.mapper.UsersMapper;
import com.example.mydemo.model.ClockVO;

import com.example.mydemo.service.IEmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
public class ClockService {

    @Autowired
    private UsersMapper userMapper;
    @Autowired
    private ClockMapper clockMapper;
    @Autowired
    private DepMapper depMapper;


    public List<ClockVO> selectDakaCount() {
        return clockMapper.selectDakaCount();
    }

        @Autowired
        private IEmployeeService employeeService; // 员工查询服务

        // 分页参数
        private static final int PAGE_SIZE = 250;
        private static final int THREAD_COUNT = 4; // 线程数

        private static final String COMPANY_LOCATION = "116.404,39.915";     // 公司位置（经纬度）
        private static final double LOCATION_OFFSET = 0.01;                  // 位置随机偏移量（±0.01度）
        private static int totalInserted = 0;

        // ====================== 随机数据配置 ======================
        private static final Random RANDOM = new Random();
        private int i =1;
        private static final int BATCH_SIZE = 500; // 每批次插入500条
        private static final int FLUSH_INTERVAL = 100; // 每生成100条触发一次插入

// 标记异步方法
@Async("taskExecutor")
public void generateAndInsertData(int i) {
    // 模拟耗时操作
    try {
        Thread.sleep(1000);
        processPage(i);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

    private void processPage(int page) {
            Page<Employee> n = new Page<>(page,PAGE_SIZE);
        System.out.println("处理第" + page + "页数据");
        List<Employee> employees = employeeService.page(n).getRecords();
//        List<Employee> employees = employeeService.queryByPage(page,PAGE_SIZE);
        System.out.println("查询完数据"+ employees.size());
        System.out.println("处理数据"+employees.get(0).getId()+" 到"+employees.get(employees.size()-1).getId());
        // 动态批次生成
        List<Clock> buffer = new ArrayList<>();
        for (Employee emp : employees) {
            // 生成打卡记录

            List<Clock> records = generateEmployeeClocks(emp);
            buffer.addAll(records);

            // 达到批次大小立即插入
            if (buffer.size() >= BATCH_SIZE) {
                System.out.println("处理员工：" + emp.getId()+"插入了"+buffer.size()+"条数据");
                clockMapper.batchInsert(buffer);
                totalInserted += buffer.size();
                buffer.clear();
                System.out.println("已插入 {} 条数据"+ totalInserted);
            }
        }

        // 处理剩余数据
        if (!buffer.isEmpty()) {
            clockMapper.batchInsert(buffer);
            totalInserted += buffer.size();
            System.out.print("最终插入剩余 {} 条数据"+ buffer.size());
        }
    }

        private List<Clock> generateEmployeeClocks(Employee emp) {
            List<Clock> records = new ArrayList<>();
            DateTimeFormatter dtFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            Random random = new Random();

            LocalDate currentDate = LocalDate.now();
            LocalDate startDate = emp.getHireDate();

            for (LocalDate date = startDate; !date.isAfter(currentDate); date = date.plusDays(1)) {
                if (date.getDayOfWeek().getValue() >= 6) continue; // 跳过周末

                int clockCount = generateDailyClockCount(random); // 生成当日打卡次数

                switch (clockCount) {
                    case 1:
                        // 随机上下班打卡
                        if (random.nextBoolean()) {
                            records.add(generateWorkRecord(Long.valueOf(emp.getEmployeeId()), date, dtFormatter, random));
                        } else {
                            records.add(generateOffRecord(Long.valueOf(emp.getEmployeeId()), date, dtFormatter, random));
                        }
                        break;
                    case 2:
                        // 完整打卡
                        records.add(generateWorkRecord(Long.valueOf(emp.getEmployeeId()), date, dtFormatter, random));
                        records.add(generateOffRecord(Long.valueOf(emp.getEmployeeId()), date, dtFormatter, random));
                        break;
                }
            }
            return records;
        }
    private static int generateDailyClockCount(Random random) {
        double probability = random.nextDouble();
        if (probability < 0.01) {
            return 0; // 20%概率不打卡
        } else if (probability < 0.02) { // 0.2-0.5为30%概率
            return 1; // 30%概率打1次
        } else {
            return 2; // 50%概率打2次
        }
    }
    private static Clock generateWorkRecord(Long employeeId, LocalDate date, DateTimeFormatter formatter,
                                            Random random) {
        // 正常时间范围（8:30-9:00）占80%，迟到（9:00-9:30）占15%，严重迟到（>9:30）占5%
        double timeProb = random.nextDouble();
        LocalTime clockTime;
        if (timeProb < 0.97) {
            // 正常时间：8:30-9:00（30分钟）
            clockTime = LocalTime.of(8, 30).plusMinutes(random.nextInt(31));
        } else if (timeProb < 0.99) {
            // 迟到：9:00-9:30（30分钟）
            clockTime = LocalTime.of(9, 0).plusMinutes(random.nextInt(31));
        } else {
            // 严重迟到：>9:30（随机）
            clockTime = LocalTime.of(9, 30).plusMinutes(random.nextInt(31));
        }

        // 判断状态（正常/迟到）
        int status;
        String remark;
        LocalTime workStart = LocalTime.of(9, 0); // 上班时间9:00
        Duration lateThreshold = Duration.ofMinutes(30); // 迟到30分钟阈值
        if (clockTime.isBefore(workStart.plus(lateThreshold))) {
            status = 1; // 正常（≤9:30）
            remark = "正常";
        } else {
            status = 2; // 迟到（>9:30）
            Duration delay = Duration.between(workStart, clockTime);
            int minutes = (int) delay.toMinutes();
            remark = String.format("迟到%d分钟", minutes);
        }

        // 生成位置（公司附近）
        String location = generateRandomLocation();

        return buildClockRecord(employeeId, 1, status, formatter.format(date.atTime(clockTime)), location, remark);
    }

    /**
     * 生成单条下班打卡记录（带随机时间+状态判断）
     */
    private static Clock generateOffRecord(Long employeeId, LocalDate date, DateTimeFormatter formatter,
                                           Random random) {
        // 正常时间范围（17:30-18:00）占85%，早退（17:00-17:30）占10%，严重早退（<17:00）占5%
        double timeProb = random.nextDouble();
        LocalTime clockTime;
        if (timeProb < 0.98) {
            // 正常时间：17:30-18:00（30分钟）
            clockTime = LocalTime.of(18, 0).plusMinutes(random.nextInt(31));
        } else if (timeProb < 0.99) {
            // 早退：17:00-17:30（30分钟）
            clockTime = LocalTime.of(17, 30).plusMinutes(random.nextInt(31));
        } else {
            // 严重早退：<17:00（随机）
            clockTime = LocalTime.of(17, 30).minusMinutes(random.nextInt(31));
        }

        // 判断状态（正常/早退）
        int status;
        String remark;
        LocalTime workEnd = LocalTime.of(18, 0); // 下班时间18:00
        if (clockTime.isAfter(workEnd)) {
            status = 1; // 正常（≥17:30）
            remark = "正常";
        } else {
            status = 3; // 早退（<17:30）
            Duration early = Duration.between(clockTime, workEnd);
            int minutes = (int) early.toMinutes();
            remark = String.format("早退%d分钟", minutes);
        }

        // 生成位置（公司附近）
        String location = generateRandomLocation();

        return buildClockRecord(employeeId, 2, status, formatter.format(date.atTime(clockTime)), location, remark);
    }

    /**
     * 生成公司位置附近的随机经纬度
     */
    private static String generateRandomLocation() {
        double[] companyCoords = parseLocation(COMPANY_LOCATION);
        double randomLon = companyCoords[0] + (RANDOM.nextDouble() - 0.5) * 2 * LOCATION_OFFSET;
        double randomLat = companyCoords[1] + (RANDOM.nextDouble() - 0.5) * 2 * LOCATION_OFFSET;
        return String.format("%.6f,%.6f", randomLon, randomLat);
    }

    /**
     * 解析位置字符串（经度,纬度）为数组
     */
    private static double[] parseLocation(String location) {
        String[] parts = location.split(",");
        return new double[]{Double.parseDouble(parts[0]), Double.parseDouble(parts[1])};
    }
    private static Clock buildClockRecord(Long empId, int type, int status,
                                          String time, String location, String remark) {
        return new Clock(
                null,       // id（自增）
                empId,
                type,
                status,
                time,
                location,
                remark
        );
    }

}
